import { ElMessage, ElNotification, ElMessageBox } from 'element-plus'

/**
 * 仓库操作错误处理器
 * 提供统一的错误处理和用户反馈机制
 */
export class WarehouseErrorHandler {
  
  /**
   * 处理API错误响应
   * @param {Object} error - 错误对象
   * @param {string} operation - 操作类型，如 '入库'、'出库'
   * @param {Object} options - 配置选项
   * @returns {Promise<boolean>} - 是否需要重试
   */
  static async handleError(error, operation = '操作', options = {}) {
    const {
      showNotification = false,
      allowRetry = true,
      duration = 4500
    } = options

    // 解析错误信息
    const errorInfo = this.parseError(error)
    
    // 根据错误类型显示不同的用户提示
    if (showNotification) {
      this.showErrorNotification(errorInfo, operation, duration)
    } else {
      this.showErrorMessage(errorInfo, operation)
    }
    
    // 记录错误日志
    this.logError(error, operation, errorInfo)
    
    // 如果允许重试且是可重试的错误，询问用户是否重试
    if (allowRetry && this.isRetriableError(errorInfo.code)) {
      return await this.promptRetry(operation)
    }
    
    return false
  }
  
  /**
   * 解析错误信息
   * @param {Object} error - 错误对象
   * @returns {Object} - 解析后的错误信息
   */
  static parseError(error) {
    // 网络错误
    if (!error.response) {
      return {
        code: 'NETWORK_ERROR',
        message: '网络连接失败，请检查网络设置',
        type: 'network',
        userMessage: '网络连接失败，请检查网络设置后重试'
      }
    }
    
    const response = error.response
    const status = response.status
    const data = response.data || {}
    
    // 根据HTTP状态码和业务错误码解析
    switch (status) {
      case 400:
        return this.parseBadRequestError(data)
      case 401:
        return {
          code: 'UNAUTHORIZED',
          message: '用户未登录或登录已过期',
          type: 'auth',
          userMessage: '登录已过期，请重新登录'
        }
      case 403:
        return {
          code: 'FORBIDDEN',
          message: '权限不足',
          type: 'auth',
          userMessage: '您没有权限执行此操作'
        }
      case 404:
        return {
          code: 'NOT_FOUND',
          message: '请求的资源不存在',
          type: 'client',
          userMessage: '请求的数据不存在，可能已被删除'
        }
      case 500:
        return {
          code: 'INTERNAL_ERROR',
          message: data.message || '服务器内部错误',
          type: 'server',
          userMessage: '服务器暂时出现问题，请稍后重试'
        }
      default:
        return {
          code: 'UNKNOWN_ERROR',
          message: data.message || '未知错误',
          type: 'unknown',
          userMessage: data.message || '操作失败，请重试'
        }
    }
  }
  
  /**
   * 解析400错误（业务逻辑错误）
   * @param {Object} data - 响应数据
   * @returns {Object} - 错误信息
   */
  static parseBadRequestError(data) {
    const code = data.code
    const message = data.message
    
    // 仓库业务特定错误码
    const warehouseErrors = {
      4001: {
        type: 'business',
        userMessage: '库存数量不足，请检查库存后重试',
        suggestion: '建议先查看库存详情，确认实际可用数量'
      },
      4002: {
        type: 'business',
        userMessage: '单据状态不允许此操作',
        suggestion: '请检查单据当前状态，确保符合操作条件'
      },
      4003: {
        type: 'business',
        userMessage: '数量验证失败，请检查输入数量',
        suggestion: '请确认输入的数量符合业务规则'
      },
      4004: {
        type: 'business',
        userMessage: '相关数据不存在，可能已被删除',
        suggestion: '请刷新页面后重试'
      },
      4009: {
        type: 'business',
        userMessage: '操作冲突，有其他用户正在处理',
        suggestion: '请稍等片刻后重试'
      }
    }
    
    if (warehouseErrors[code]) {
      return {
        code: code,
        message: message,
        type: warehouseErrors[code].type,
        userMessage: message || warehouseErrors[code].userMessage,
        suggestion: warehouseErrors[code].suggestion
      }
    }
    
    // 通用业务错误
    return {
      code: code || 'VALIDATION_ERROR',
      message: message,
      type: 'business',
      userMessage: message || '数据验证失败，请检查输入信息'
    }
  }
  
  /**
   * 显示错误消息
   * @param {Object} errorInfo - 错误信息
   * @param {string} operation - 操作类型
   */
  static showErrorMessage(errorInfo, operation) {
    const message = `${operation}失败: ${errorInfo.userMessage}`
    ElMessage.error({
      message: message,
      duration: 4500,
      showClose: true
    })
  }
  
  /**
   * 显示错误通知
   * @param {Object} errorInfo - 错误信息
   * @param {string} operation - 操作类型
   * @param {number} duration - 显示时长
   */
  static showErrorNotification(errorInfo, operation, duration) {
    let title = `${operation}失败`
    let type = 'error'
    
    // 根据错误类型调整通知样式
    if (errorInfo.type === 'network') {
      title = '网络连接问题'
      type = 'warning'
    } else if (errorInfo.type === 'auth') {
      title = '身份验证失败'
    }
    
    ElNotification({
      title: title,
      message: errorInfo.userMessage + (errorInfo.suggestion ? `<br><br>💡 ${errorInfo.suggestion}` : ''),
      type: type,
      duration: duration,
      dangerouslyUseHTMLString: true,
      position: 'top-right'
    })
  }
  
  /**
   * 判断是否为可重试的错误
   * @param {string} code - 错误码
   * @returns {boolean} - 是否可重试
   */
  static isRetriableError(code) {
    const retriableErrors = [
      'NETWORK_ERROR',
      'INTERNAL_ERROR',
      4009  // 并发操作异常
    ]
    return retriableErrors.includes(code)
  }
  
  /**
   * 提示用户是否重试
   * @param {string} operation - 操作类型
   * @returns {Promise<boolean>} - 用户是否选择重试
   */
  static async promptRetry(operation) {
    try {
      await ElMessageBox.confirm(
        `${operation}失败，是否重试？`,
        '操作失败',
        {
          confirmButtonText: '重试',
          cancelButtonText: '取消',
          type: 'warning'
        }
      )
      return true
    } catch {
      return false
    }
  }
  
  /**
   * 记录错误日志
   * @param {Object} error - 原始错误对象
   * @param {string} operation - 操作类型
   * @param {Object} errorInfo - 解析后的错误信息
   */
  static logError(error, operation, errorInfo) {
    const logData = {
      timestamp: new Date().toISOString(),
      operation: operation,
      errorCode: errorInfo.code,
      errorType: errorInfo.type,
      message: errorInfo.message,
      userAgent: navigator.userAgent,
      url: window.location.href
    }
    
    // 开发环境下在控制台显示详细信息
    if (process.env.NODE_ENV === 'development') {
      console.group(`🚨 ${operation}操作异常`)
      console.error('错误信息:', errorInfo)
      console.error('原始错误:', error)
      console.error('日志数据:', logData)
      console.groupEnd()
    }
    
    // 生产环境下可以发送到日志服务
    // TODO: 集成日志服务（如Sentry、LogRocket等）
  }
}

/**
 * 仓库操作成功处理器
 */
export class WarehouseSuccessHandler {
  
  /**
   * 处理成功操作
   * @param {string} operation - 操作类型
   * @param {Object} data - 返回数据
   * @param {Object} options - 选项
   */
  static handleSuccess(operation, data = null, options = {}) {
    const {
      showMessage = true,
      showNotification = false,
      autoRefresh = true,
      duration = 3000
    } = options
    
    if (showNotification) {
      ElNotification.success({
        title: '操作成功',
        message: `${operation}操作已完成`,
        duration: duration
      })
    } else if (showMessage) {
      ElMessage.success({
        message: `${operation}成功`,
        duration: duration
      })
    }
    
    // 记录成功日志
    if (process.env.NODE_ENV === 'development') {
      console.log(`✅ ${operation}操作成功`, data)
    }
  }
}

/**
 * 导出快捷方法
 */
export const handleWarehouseError = WarehouseErrorHandler.handleError.bind(WarehouseErrorHandler)
export const handleWarehouseSuccess = WarehouseSuccessHandler.handleSuccess.bind(WarehouseSuccessHandler)